Database systems and applications implemented using data structures with large data sets and high throughput applications can challenge the capacity of a single server. High query rates can exhaust the processor capacity of the server. Larger data sets can exceed the storage capacity of a single machine. Finally, working set sizes larger than the system's memory stress the input/output (I/O) capacity of disk drives. To address these issues of scale, two basic approaches have been developed: vertical scaling and sharding.
Vertical scaling adds more CPU and storage resources to increase capacity. However, scaling by adding capacity has limitations: high performance systems with large numbers of CPUs and large amount of RAM are disproportionately more expensive than smaller systems. Additionally, cloud-based providers may only allow users to provision smaller instances. As a result there is a practical maximum capability for vertical scaling.
In contrast, sharding, or horizontal scaling, divides the data set and distributes the data over multiple servers, or shards. Each shard includes an independent database, and collectively, the shards include a single logical database. Sharding addresses the challenge of scaling to support high throughput and large data sets. In a simple example, each of several shards can be implemented on a separate instance of a server with each server running on a separate virtual machine. Sharding reduces the number of operations each server handles. Each shard processes fewer operations as the cluster of servers grows. As a result, shared clusters can increase capacity and throughput horizontally. For example, to store data, an application only needs to access the shard responsible for the relevant records. Sharding also reduces the amount of data that each server needs to store. Each shard stores less data as the cluster grows. For example, if an application has a one terabyte data set, and there are four shards, then each shard might hold only 256 GB of data. If there are 40 shards, then each shard might hold only 25 GB of data.
Sharding can also be used to add fault tolerance to a system by segregating traffic to one or more duplicates of the system. Sharding a single instance/server is relatively simple because doing so only requires replicating the system and introducing some routing of traffic. In highly distributed systems however, the present inventors have observed that significant complexities arise because of the implicit and explicit relationships between communicating systems and, with respect to online gaming, the complex game/business logic the systems may maintain.
The present inventors have also observed that sharding approaches are historically reactive rather than proactive. Modern distributed, highly concurrent systems are typically required to be built to function in an environment where the systems are in a constant state of failure. Further, systems that provide online gaming, which is becoming more regulated, have the additional requirement of being able to operate with constraints on where the systems are deployed. Thus, what is need are systems, methods, and apparatus that provide an efficient and cost effective solution to these (and other) problems.